package org.infodavid.common.persistence;

import java.io.Serializable;
import java.sql.Connection;
import java.util.Collection;
import java.util.List;
import java.util.Stack;

import javax.persistence.PersistenceException;
import javax.persistence.criteria.CriteriaBuilder;

import org.infodavid.common.persistence.ILockable.ELockType;
import org.infodavid.common.util.IVisitor;

/**
 * The Class PersistenceSessionWrapper.
 */
@SuppressWarnings("rawtypes")
public class PersistenceSessionWrapper extends PersistenceSession {

  /** The delegate. */
  private final PersistenceSession delegate;

  /** The inserted data. */
  private final Stack<IPersistentData> insertedData = new Stack<IPersistentData>();

  /**
   * Instantiates a new persistence session wrapper.
   * @param provider the provider
   * @param dlg the delegate session
   */
  public PersistenceSessionWrapper(IBasicPersistenceProvider provider, PersistenceSession dlg) {
    super(provider);

    delegate = dlg;
  }

  /*
   * (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#doClose()
   */
  @Override
  protected void doClose() throws PersistenceException {
    insertedData.clear();
    delegate.doClose();
  }

  /*
   * (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#doExecuteQuery(java .lang.Class,
   * java.lang.String, java.util.List, boolean)
   */
  @Override
  protected <T> Object doExecuteQuery(Class<T> clazz, String queryName,
      List<IQueryParameter> parameters, boolean single) throws PersistenceException {
    return delegate.doExecuteQuery(clazz, queryName, parameters, single);
  }

  /*
   * (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#doFindEntities(java .lang.Class,
   * java.lang.String, java.util.List)
   */
  @Override
  protected <T extends IPersistentData> List<T> doFindEntities(Class<T> entityClass,
      String queryName, List<IQueryParameter> parameters) throws PersistenceException {
    return delegate.doFindEntities(entityClass, queryName, parameters);
  }

  /*
   * (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#doGetTransaction()
   */
  @Override
  protected ITransaction doGetTransaction() throws PersistenceException {
    return delegate.doGetTransaction();
  }

  /*
   * (non-Javadoc)
   * @see java.lang.Object#equals(java.lang.Object)
   */
  @Override
  public boolean equals(Object obj) {
    return delegate.equals(obj);
  }

  /*
   * (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#flush()
   */
  @Override
  public void flush() throws PersistenceException {
    delegate.flush();
  }

  /*
   * (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#getConnection()
   */
  @Override
  public Connection getConnection() throws PersistenceException {
    return delegate.getConnection();
  }

  /*
   * (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#getCriteriaBuilder()
   */
  @Override
  public CriteriaBuilder getCriteriaBuilder() throws PersistenceException {
    return delegate.getCriteriaBuilder();
  }

  /*
   * (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#getDelegate()
   */
  @Override
  public Object getDelegate() throws PersistenceException {
    return delegate.getDelegate();
  }

  /**
   * Gets the inserted data.
   * @return the inserted data
   */
  public Stack<IPersistentData> getInsertedData() {
    return insertedData;
  }

  /*
   * (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#getProvider()
   */
  @Override
  public IBasicPersistenceProvider getProvider() {
    return delegate.getProvider();
  }

  /*
   * (non-Javadoc)
   * @see java.lang.Object#hashCode()
   */
  @Override
  public int hashCode() {
    return delegate.hashCode();
  }

  /*
   * (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#initialize()
   */
  @Override
  protected void initialize() throws PersistenceException {}

  /*
   * (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#isOpen()
   */
  @Override
  public boolean isOpen() throws PersistenceException {
    return delegate.isOpen();
  }

  /*
   * (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#isTransactionActive()
   */
  @Override
  public boolean isTransactionActive() {
    return delegate.isTransactionActive();
  }

  /**
   * See super class or interface. (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#doExecuteNamedQuery(java.lang.Class,
   *      java.lang.String, java.util.List, boolean)
   */
  @Override
  protected <T> Object doExecuteNamedQuery(Class<T> clazz, String queryName,
      List<IQueryParameter> parameters, boolean single) throws PersistenceException {
    return delegate.doExecuteNamedQuery(clazz, queryName, parameters, single);
  }

  /**
   * See super class or interface. (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#doFindEntitiesWithNamedQuery(java.lang.Class,
   *      java.lang.String, java.util.List)
   */
  @Override
  protected <T extends IPersistentData> List<T> doFindEntitiesWithNamedQuery(Class<T> entityClass,
      String queryName, List<IQueryParameter> parameters) throws PersistenceException {
    return delegate.doFindEntitiesWithNamedQuery(entityClass, queryName, parameters);
  }

  /**
   * See super class or interface. (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#doFindEntityWithNamedQuery(java.lang.Class,
   *      java.lang.String, java.io.Serializable,
   *      org.infodavid.common.persistence.ILockable.ELockType)
   */
  @Override
  protected <T extends IPersistentData> T doFindEntityWithNamedQuery(Class<T> entityClass,
      String queryName, Serializable key, ELockType lockType) throws PersistenceException {
    return delegate.doFindEntityWithNamedQuery(entityClass, queryName, key, lockType);
  }

  /**
   * See super class or interface. (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#doFindEntity(java.lang.Class,
   *      java.io.Serializable, org.infodavid.common.persistence.ILockable.ELockType)
   */
  @Override
  protected <T extends IPersistentData> T doFindEntity(Class<T> entityClass, Serializable key,
      ELockType lockType) throws PersistenceException {
    return delegate.doFindEntity(entityClass, key, lockType);
  }

  /**
   * See super class or interface. (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#doInsertEntities(java.util.Collection,
   *      org.infodavid.common.util.IVisitor)
   */
  @Override
  protected <T extends IPersistentData> List<T> doInsertEntities(Collection<T> entities,
      IVisitor<T,Object> visitor) throws PersistenceException {
    return delegate.doInsertEntities(entities, visitor);
  }

  /**
   * See super class or interface. (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#doInsertEntity(org.infodavid.common.persistence.IPersistentData)
   */
  @Override
  protected <T extends IPersistentData> T doInsertEntity(T entity) throws PersistenceException {
    return delegate.doInsertEntity(entity);
  }

  /**
   * See super class or interface. (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#doLock(org.infodavid.common.persistence.ILockable,
   *      org.infodavid.common.persistence.ILockable.ELockType)
   */
  @Override
  protected void doLock(ILockable lockable, ELockType type) throws PersistenceException {
    delegate.doLock(lockable, type);
  }

  /**
   * See super class or interface. (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#doRemove(java.lang.Class,
   *      java.util.Collection, org.infodavid.common.util.IVisitor)
   */
  @Override
  protected <K extends Serializable,T extends IPersistentData<K>> void doRemove(
      Class<T> entityClass, Collection<K> keys, IVisitor<K,Object> visitor)
      throws PersistenceException {
    delegate.doRemove(entityClass, keys, visitor);
  }

  /**
   * See super class or interface. (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#doRemove(java.lang.Class,
   *      java.io.Serializable)
   */
  @Override
  protected <K extends Serializable,T extends IPersistentData<K>> void doRemove(
      Class<T> entityClass, K key) throws PersistenceException {
    delegate.doRemove(entityClass, key);
  }

  /**
   * See super class or interface. (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#doRemoveEntities(java.util.Collection,
   *      org.infodavid.common.util.IVisitor)
   */
  @Override
  protected <T extends IPersistentData> void doRemoveEntities(Collection<T> entities,
      IVisitor<T,Object> visitor) throws PersistenceException {
    delegate.doRemoveEntities(entities, visitor);
  }

  /**
   * See super class or interface. (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#doRemoveEntity(org.infodavid.common.persistence.IPersistentData)
   */
  @Override
  protected <T extends IPersistentData> void doRemoveEntity(T entity) throws PersistenceException {
    delegate.doRemoveEntity(entity);
  }

  /**
   * See super class or interface. (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#doUpdateEntities(java.util.Collection,
   *      org.infodavid.common.util.IVisitor)
   */
  @Override
  protected <T extends IPersistentData> Collection<T> doUpdateEntities(Collection<T> entities,
      IVisitor<T,Object> visitor) throws PersistenceException {
    return delegate.doUpdateEntities(entities, visitor);
  }

  /**
   * See super class or interface. (non-Javadoc)
   * @see org.infodavid.common.persistence.PersistenceSession#doUpdateEntity(org.infodavid.common.persistence.IPersistentData)
   */
  @Override
  protected <T extends IPersistentData> T doUpdateEntity(T entity) throws PersistenceException {
    return delegate.doUpdateEntity(entity);
  }
}
